package XishiBackend;

import javax.servlet.http.HttpSession;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Component;

import XishiBackend.base.Constant;
import XishiBackend.base.Json;
import XishiBackend.base.Encrypt;
import XishiBackend.models.repository.RestaurantRepository;

@Aspect
@Component
@EnableAutoConfiguration
public class Aop {
    @Autowired
    private RestaurantRepository rR;
    
    @Around("execution(public String controllers.*.*.*(..))")
    public String performanceAnalysis(ProceedingJoinPoint pjp) throws Throwable{
        long before = System.currentTimeMillis();
        
        String param = "";
        for(Object i:pjp.getArgs()) {
            param += i.toString()+" ";
        }
        System.out.println("Param:"+param);
        
        String r = (String)pjp.proceed();
        long after = System.currentTimeMillis();
        System.out.println(pjp + " spends " + (after-before) + " milliseconds.");
        return r;
    }
    
    @Around("execution(public String controllers.microsite.*.*(..))")
    public String validateMicrositeSignature(ProceedingJoinPoint pjp) throws Throwable {
        if(pjp.toString().equals("execution(String XishiBackend.controllers.microsite.MicrositeOrderController.pay(String))")) {
            return (String) pjp.proceed();
        }
        if(pjp.toString().equals("execution(String XishiBackend.controllers.microsite.MicrositeUserController.wxtakein(String,String,int,String))")) {
            return (String) pjp.proceed();
        }
        String failMsg = Json.format(255, "签名验证失败");
        Object[] args = pjp.getArgs();
        if(args.length == 0) {
            return failMsg;
        }
        String sig = pjp.getArgs()[0].toString();
        if(validateSignature(sig)) {
            return pjp.proceed().toString();
        }
        else {
            return failMsg;
        }
    }
    
    @Around("execution(public String controllers.android.*.*(..))")
    public String validateAndroidSignature(ProceedingJoinPoint pjp) throws Throwable {
        if(pjp.toString().equals("execution(String XishiBackend.controllers.microsite.MicrositeOrderController.pay(String))")) {
            return (String) pjp.proceed();
        }
        String failMsg = Json.format(255, "签名验证失败");
        Object[] args = pjp.getArgs();
        if(args.length == 0) {
            return failMsg;
        }
        String sig = pjp.getArgs()[0].toString();
        if(validateSignature(sig)) {
            return pjp.proceed().toString();
        }
        else {
            return failMsg;
        }
    }
    
    @Around("execution(public String controllers.web.WebBaseController.page*(..))")
    public String pageAspect(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        HttpSession session = (HttpSession) args[0];
        
        if(session == null || session.getAttribute("isLogin") == null) {
            return "login";
        }
        if((boolean)session.getAttribute("isLogin") == false) {
            return "login";
        }
        return (String) pjp.proceed(args);
    }
    
    @Around("execution(public String controllers.web.action.*.*(..))")
    public String actionAspect(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        HttpSession session = (HttpSession) args[0];
        if(session != null && (boolean)session.getAttribute("isLogin")) {
            return (String) pjp.proceed(args);
        }
        return Json.format(255, "请先登录");
    }
    
    private boolean validateSignature(String sig){
//        Date now = new Date();
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH");
//        String date = sdf.format(now);
//        String localSig = MD5Util.MD5(
//            MD5Util.MD5(Constant.APP_KEY) + "#" + MD5Util.MD5(date)
//        );
//        return localSig.equals(sig);
        String localSig = Encrypt.MD5(Constant.APP_KEY);
        return localSig.equals(sig);
    }
}
